/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.lidovky.articles;

import cz.mzk.lidovky.articles.domain.Article;
import cz.mzk.lidovky.articles.domain.Author;
import java.io.PrintStream;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 *
 * @author Martin Řehánek (rehan@mzk.cz)
 */
public class AuthorStatistics {

    private List<Article> articles;
    private int articlesWithAuthor = 0;
    private SortedMap<String, Integer> authorsWithSurname = new TreeMap<String, Integer>();
    private SortedMap<String, Integer> authorsWithNamesAndSurname = new TreeMap<String, Integer>();
    private SortedMap<String, Integer> authorsUnresolved = new TreeMap<String, Integer>();
    private SortedMap<String, Integer> authorsWithNick = new TreeMap<String, Integer>();
    private int authorsNull = 0;

    public AuthorStatistics(List<Article> articles) {
        this.articles = articles;
        processArticles();
    }

    private void processArticles() {
        for (Article article : articles) {
            Author author = article.getAuthor();
            if (author != null && author.getUnresolvedName() != null) {
                String unresolvedName = author.getUnresolvedName();
                articlesWithAuthor++;
                if (author.hasNick()) {
                    updateCounter(unresolvedName, authorsWithNick);
                } else if (!author.hasFirstNames() && author.hasSurname()){
                    updateCounter(unresolvedName, authorsWithSurname);
                }else if (author.hasFirstNames()) {
                    updateCounter(unresolvedName, authorsWithNamesAndSurname);
                } else {
                    updateCounter(unresolvedName, authorsUnresolved);
                }
            } else {
                updateNullCounter();
            }
        }
    }

    private void updateCounter(String string, SortedMap<String, Integer> map) {
        Integer counter;
        if (map.containsKey(string)) {
            counter = Integer.valueOf(map.get(string) + 1);
        } else {
            counter = Integer.valueOf(1);
        }
        map.put(string, counter);
    }

    private void updateNullCounter() {
        authorsNull++;
    }

    /**
     * Prints statistics about author names
     * @param detailed
     * @param out
     */
    public void printStatistics(PrintStream out, boolean detailed) {
        out.println("Author statistics: ");
        out.println("===================");
        out.println("articles: " + articles.size());
        out.println("articles with author: " + articlesWithAuthor);
        out.println("authors with surname: " + authorsWithSurname.size());
        out.println("authors with names and surname: " + authorsWithNamesAndSurname.size());
        out.println("unresolved authors: " + authorsUnresolved.size());
        out.println("missing author: " + authorsNull);
        if (detailed) {
            out.println("");
            out.println("details:");
            out.println("---------");
            out.println("Authors with just surname: ");
            printAuthorsWithSurname(out);
            out.println("Authors with name and surname: ");
            printAuthorsWithNamesAndSurname(out);
            out.println("Authors with nicks:");
            printAuthorsWithNick(out);
            out.println("Unresolved authors:");
            printUnresolvedAuthors(out);
        }
    }

    public void printAuthorsWithSurname(PrintStream out){
        //out.println("Authors with name and surname: ");
        Set<String> keys = authorsWithSurname.keySet();
        SortedMap<String, Author> authors = new TreeMap<String, Author>();
        for (Article article : articles) {
            Author author = article.getAuthor();
            if (author != null && author.getUnresolvedName() != null) {
                String name = author.getUnresolvedName();
                if (keys.contains(name)) {
                    authors.put(name, author);
                }
            }
        }
        for (String unresolvedName : authors.keySet()) {
            Author author = authors.get(unresolvedName);
            out.println("'" + author.getFirstNames() + "' '" + author.getSurname() + "'");
        }
    }

    public void printAuthorsWithNamesAndSurname(PrintStream out) {
        //out.println("Authors with name and surname: ");
        Set<String> keys = authorsWithNamesAndSurname.keySet();
        SortedMap<String, Author> authors = new TreeMap<String, Author>();
        for (Article article : articles) {
            Author author = article.getAuthor();
            if (author != null && author.getUnresolvedName() != null) {
                String name = author.getUnresolvedName();
                if (keys.contains(name)) {
                    authors.put(name, author);
                }
            }
        }
        for (String unresolvedName : authors.keySet()) {
            Author author = authors.get(unresolvedName);
            out.println("'" + author.getFirstNames() + "' '" + author.getSurname() + "'");
        }
    }

    public void printUnresolvedAuthors(PrintStream out) {
        for (String name : authorsUnresolved.keySet()) {
            out.println(" '" + name + "': " + authorsUnresolved.get(name));
        }
    }

    public void printAuthorsWithNick(PrintStream out) {
        //out.println("Authors with nicks:");
        Set<String> keys = authorsWithNick.keySet();
        SortedMap<String, Author> authors = new TreeMap<String, Author>();
        for (Article article : articles) {
            Author author = article.getAuthor();
            if (author != null && author.getUnresolvedName() != null) {
                String name = author.getUnresolvedName();
                if (keys.contains(name)) {
                    authors.put(name, author);
                }
            }
        }
        for (String unresolvedName : authors.keySet()) {
            Author author = authors.get(unresolvedName);
            out.println("'" + author.getNick() + "' = '" + author.getFirstNames() + "' '" + author.getSurname() + "'");
        }
    }
}
